export default {
  // 去抖：在事件被触发n秒后再执行回调，如果在这n秒内又被触发，则重新计时。
  // click: debounce(function() { console.log('业务代码') }, 3000)
  debounce(fn, wait) {
    let callback = fn
    let timerId = null

    const debounced = () => {
      // 保存作用域
      let context = this
      // 保存参数，例如 event 对象
      let args = arguments
      clearTimeout(timerId)
      timerId = setTimeout(() => {
        callback.apply(context, args)
      }, wait)
    }
    // 返回一个闭包
    return debounced
  },

  // 节流：规定在一个单位时间内，只能触发一次函数。如果这个单位时间内触发多次函数，只有一次生效。
  // click: throttle(function() { console.log('业务代码') }, 3000)
  throttle(fn, wait) {
    let callback = fn
    let timerId = null
    // 是否是第一次执行
    let firstInvoke = true
    const throttled = () => {
      let context = this
      let args = arguments
      // 如果是第一次触发，直接执行
      if (firstInvoke) {
        callback.apply(context, args)
        firstInvoke = false
        return
      }
      // 如果定时器已存在，直接返回。        
      if (timerId) {
        return
      }
      timerId = setTimeout(() => {
        // 注意这里 将 clearTimeout 放到 内部来执行了
        clearTimeout(timerId)
        timerId = null
        callback.apply(context, args)
      }, wait)
    }
    // 返回一个闭包
    return throttled
  },

  // 时间戳格式化
  formatDate(date, kind) {
    kind = kind ? kind : 1
    let yyyy = date.getFullYear()
    let mm = date.getMonth() + 1
    mm = mm < 10 ? ('0' + mm) : mm
    let dd = date.getDate()
    dd = dd < 10 ? ('0' + dd) : dd
    // kind为2时，带时间
    if(kind === 2) {
      let hh = date.getHours()
      hh = hh < 10 ? ('0' + hh) : hh
      let mi = date.getMinutes()
      mi = mi < 10 ? ('0' + mi) : mi
      let ss = date.getSeconds()
      ss = ss < 10 ? ('0' + ss) : ss
      return yyyy + '-' + mm + '-' + dd + ' ' + hh + ':' + mi + ':' + ss
    }
    return yyyy + '-' + mm + '-' + dd
  },

  // 起止时间戳格式化
  formatDateRange(dateArr, kind) {
    if(dateArr.length === 2 && dateArr[0] && dateArr[1]) {
      kind = kind ? kind : 1
      let beginStr, endStr
      let beginDate = dateArr[0]
      let endDate = dateArr[1]
      let yyyy = beginDate.getFullYear()
      let mm = beginDate.getMonth() + 1
      mm = mm < 10 ? ('0' + mm) : mm
      let dd = beginDate.getDate()
      dd = dd < 10 ? ('0' + dd) : dd
      beginStr = yyyy + '-' + mm + '-' + dd
      yyyy = endDate.getFullYear()
      mm = endDate.getMonth() + 1
      mm = mm < 10 ? ('0' + mm) : mm
      dd = endDate.getDate()
      dd = dd < 10 ? ('0' + dd) : dd
      endStr = yyyy + '-' + mm + '-' + dd
      // kind为2时，带时间
      if(kind === 2) {
        let hh = beginDate.getHours()
        hh = hh < 10 ? ('0' + hh) : hh
        let mi = beginDate.getMinutes()
        mi = mi < 10 ? ('0' + mi) : mi
        let ss = beginDate.getSeconds()
        ss = ss < 10 ? ('0' + ss) : ss
        beginStr = yyyy + '-' + mm + '-' + dd + ' ' + hh + ':' + mi + ':' + ss
        hh = endDate.getHours()
        hh = hh < 10 ? ('0' + hh) : hh
        mi = endDate.getMinutes()
        mi = mi < 10 ? ('0' + mi) : mi
        ss = endDate.getSeconds()
        ss = ss < 10 ? ('0' + ss) : ss
        endStr = yyyy + '-' + mm + '-' + dd + ' ' + hh + ':' + mi + ':' + ss
      }
      return beginStr + '~' + endStr
    }
    return ''
  },

  // 弹框提示, timer为毫秒
  msg(content, timer=3000) {
    uni.showToast({ icon:'none', title: content, duration: timer })
  },

  // 显示加载中
  showLoading(content='玩命加载中...', mask=true) {
    uni.showLoading({ title: content, mask: mask })
  },

  // 隐藏加载中, timer为毫秒
  hideLoading(timer=0) {
    if(timer > 0) {
      var t = setTimeout(() => {
        uni.hideLoading()
        clearTimeout(t)
      }, timer)
    } else {
      uni.hideLoading()
    }
  },

  // 判断数组中是否存在某个元素
  izInArray(item, array) {
    let flag = false
    for(let i in array) {
      if(array[i] == item) {
        flag = true
        break
      }
    }
    return flag
  },

  // 判断是否为特定格式
  izDataType(data, type) {
    return Object.prototype.toString.call(data) === '[object '+type+']'
  },

  // 左替换
  ltrim(str, char) {
    let pos = str.indexOf(char)
    let sonstr = str.substr(pos+1)
    return sonstr
  },

  // 右替换
  rtrim(str,char) {
    let pos = str.lastIndexOf(char)
    let sonstr = str.substr(0,pos)
    return sonstr
  },

  // 保留当前页面，跳转到应用内的某个页面，使用uni.navigateBack可以返回到原页面
  navigateTo(url, params) {
    uni.navigateTo({ url: parseUrl(url, params) })
  },

  // 关闭当前页面，跳转到应用内的某个页面
  redirectTo(url, params) {
    uni.redirectTo({ url: parseUrl(url, params) })
  },

  // 关闭所有页面，打开到应用内的某个页面
  reLaunch(url,params) {
    uni.reLaunch({ url: parseUrl(url,params) })
  },

  // 跳转到 tabBar 页面，并关闭其他所有非 tabBar 页面
  switchTab(url, params) {
    uni.switchTab({ url: parseUrl(url, params) })
  },

  // 关闭当前页面，返回上一页面或多级页面
  navigateBack(delta) {
    uni.navigateBack({ delta })
  },

  // 预加载页面，是一种性能优化技术。被预载的页面，在打开时速度更快
  preloadPage(preUrl, params) {
    let url = parseUrl(preUrl, params)
    uni.preloadPage({ url })
  },

  /**
   * 功能：路由解析并且拼接
   * 使用：parseUrl('home', {id: 1, type: 'add'})
   * 得到：'/pages/home?id=1&type=add'
   */
  parseUrl(url, params) {
    let arr = []
    let wholeUrl = ''
    for(let i in params) {
        arr.push(i + "=" + params[i])
    }
    wholeUrl = "/pages/" + url
    if(arr.length > 0) {
        wholeUrl += "?" + arr.join("&")
    }
    return wholeUrl
  },

  // 获取href页面参数key
  getParams(key) {
    const reg = new RegExp('(^|&)' + key + '=([^&]*)(&|$)')
    const r = window.location.search.substr(1).match(reg)
    if (r != null) return unescape(r[2])
    return null
  },

  // 获取url中的参数key
  getParamsFromUrl(url, key) {
    const reg = new RegExp('(^|&)' + key + '=([^&]*)(&|$)')
    const r = url.substr(url.indexOf('?') + 1).match(reg)
    if (r != null) return unescape(r[2])
    return null
  },

  // 返回上一页
  prePage() {
    let curPages = getCurrentPages()
    let prePage = curPages[pages.length - 2]
    // #ifdef H5
    return prePage
    // #endif
    return prePage.$vm
  },

  // rpx转px
  rpx2px(num) {
    return uni.upx2px(num)
  },

  // px转rpx
  px2rpx(num) {
    return num/(uni.upx2px(num)/num)
  },

  // 获取窗口的宽高
  getSystemInfo() {
    const info = uni.getSystemInfoSync()
    return { w: info.windowWidth, h: info.windowHeight }
  },
}
